/// <summary>
/// Copyright 2010 Ivo Limmen (ivo@limmen.org)
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
/// 
/// http://www.apache.org/licenses/LICENSE-2.0
/// 
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
/// </summary>

using System;
using System.Collections.Generic;

using ServiceController.Api;
using Services.TaskService.Api;
using Util.Reflection;
using Services.Logging.Api;
using Services.Configuration.Api;
using System.IO;
using System.Diagnostics;

namespace Services.TaskService
{
	public class TaskService : BaseService
	{	
		private List<TaskExecutionMonitor> tasks = new List<TaskExecutionMonitor>();		
				
		private ILogService logService = null;

		public TaskService()
			: base("TaskService", "Service for scheduling tasks.")
		{		
		}
		
		public override void Initialize()
		{
			this.logService = (ILogService) GetService("LogService");

            GetLogger().Info("Loading and starting tasks...");

            string includePath = GetLocalConfiguration().GetSetting(null, "services", "include-path");

            List<ITask> tasks = new List<ITask>();
            LoadTasks(tasks, AppDomain.CurrentDomain.BaseDirectory);

            if (!string.IsNullOrEmpty(includePath))
            {
                includePath = includePath.Replace('\n', ' ');
                includePath = includePath.Replace('\r', ' ');
                includePath = includePath.Trim();

                foreach (string path in includePath.Split(new char[] { ';' }))
                {
                    string newPath = path.Trim();

                    if (Directory.Exists(newPath))
                    {
                        LoadTasks(tasks, newPath);
                    }
                }
            }

            foreach (ITask task in tasks)
            {
                InitializeTask(task);
                this.tasks.Add(new TaskExecutionMonitor(task, this.GetLogger()));
            }
        }

        private void LoadTasks(List<ITask> tasks, string directory)
        {
            ImplementationFinder serviceFinder = new ImplementationFinder(directory, false);
            tasks.AddRange(serviceFinder.GetImplementations<ITask>());
        }

		private void InitializeTask(ITask task) 
		{
			string logName = task.GetName().Replace(" ", "-").ToLower();
			
			task.SetLogger(this.logService.GetLogger("Task-" + logName));
            task.SetConfiguration(this.GetLocalConfiguration());
			task.Initialize();
		}
		
		public override string[] GetRequiredServices() 
		{
			return new string[] { "LogService", "ConfigService" };
		}			
	}
}
